import datetime
from decimal import Decimal

import pandas as pd
import tushare as ts
from flask import views

from server.apps.trade_day.views import TradeDay
from server.utils.restful import rest_success, rest_error


class ShareSelectView(views.MethodView):
    @staticmethod
    def get():
        trade_day = TradeDay().get_last_trade_day()

        url = "https://csi-web-dev.oss-cn-shanghai-finance-1-pub.aliyuncs.com/static/html/csindex/public/uploads/"
        url = url + "file/autofile/cons/000300cons.xls"
        stocks = pd.read_excel(url, dtype=str)
        stocks.rename(
            columns={"成分券代码Constituent Code": "stock", "成分券名称Constituent Name": "name", "交易所Exchange": "place"},
            inplace=True)
        stocks = stocks[["stock", "name", "place"]]
        stocks["stock_place"] = stocks.apply(
            lambda x: x["stock"] + ".SZ" if "深圳" in x["place"] else x["stock"] + ".SH", axis=1)
        stock_list = list(stocks["stock_place"])

        last_trade = trade_day.strftime("%Y%m%d")
        pro = ts.pro_api(token="68ece19b0576673a29a9fff7b3eac980c6170f8e7ea1a05774f3cf9c")
        result = pd.DataFrame()
        for i in range(3):
            ts_code = ",".join(stock_list[i * 100: (i + 1) * 100])
            ts_result = pro.daily(ts_code=ts_code, start_date=last_trade, end_date=last_trade)
            result = result.append(ts_result)
        result = result[result["close"] < 20]

        start_date = trade_day - datetime.timedelta(days=400)
        start_date = start_date.strftime("%Y%m%d")
        stock_list = list(result["ts_code"])
        times = int(len(stock_list) / 10) + 1
        result = pd.DataFrame()
        for i in range(times):
            ts_code = ",".join(stock_list[i * 10: (i + 1) * 10])
            ts_result = pro.daily(ts_code=ts_code, start_date=start_date, end_date=last_trade)
            result = result.append(ts_result)
        result.sort_values(by=["ts_code", "trade_date"], inplace=True)

        result = result[["ts_code", "trade_date", "close", "low"]]
        out = pd.DataFrame()
        for stock in stock_list:
            df = result[result["ts_code"] == stock]
            df["ma10"] = df["close"].rolling(10).mean()
            df["ma250"] = df["close"].rolling(250).mean()
            df[["buy", "width"]] = df.apply(lambda x: ShareSelectView.advise(x), axis=1, result_type="expand")
            out = out.append(df.iloc[-1])
        if out.empty:
            return rest_error(message="没有适合的股票")
        out = out[out["buy"] != 0]
        out.sort_values(by=["width"], inplace=True)
        out = out.head(10)
        return rest_success(message="获取到{}条数据".format(out.shape[0]), data=out.to_dict(orient="records"))

    @staticmethod
    def advise(row):
        buy = Decimal(0)
        width = None
        if row["ma250"] < row["close"] < row["ma10"]:
            buy = Decimal(round((row["close"] + row["low"]) / 2.0, 2))
            width = Decimal(round((row["ma10"] - row["ma250"]) / ((row["ma10"] + row["ma250"]) / 2) * 100, 2))
        return buy, width
